package com.lhd.qd.module.system.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lhd.qd.common.base.BaseServiceImpl;
import com.lhd.qd.common.consts.dict.DictTypeCodeEnum;
import com.lhd.qd.common.translator.DBTransRule;
import com.lhd.qd.common.translator.DictTransRule;
import com.lhd.qd.common.translator.TransUtils;
import com.lhd.qd.common.util.CommonUtils;
import com.lhd.qd.common.util.SecurityUtils;
import com.lhd.qd.common.util.UserUtils;
import com.lhd.qd.config.QdProperties;
import com.lhd.qd.module.system.employee.dao.EmployeeMapper;
import com.lhd.qd.module.system.role.dao.RoleMapper;
import com.lhd.qd.module.system.user.dao.UserMapper;
import com.lhd.qd.module.system.user.model.converter.AbstractUserConverter;
import com.lhd.qd.module.system.user.model.dataobj.UserDO;
import com.lhd.qd.module.system.user.model.dto.UserPageQuery;
import com.lhd.qd.module.system.user.model.dto.UserSaveDTO;
import com.lhd.qd.module.system.user.model.vo.UserDetailVO;
import com.lhd.qd.module.system.user.model.vo.UserListVO;
import com.lhd.qd.module.system.user.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;

@Service
public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO> implements UserService {

    @Autowired
    private QdProperties qdProperties;

    @Override
    public IPage<UserListVO> pageUser(UserPageQuery query) {

        QueryWrapper<UserDO> queryWrapper = Wrappers.<UserDO>query()
                .like(StringUtils.isNotEmpty(query.getEmployeeName()), "employee.name", query.getEmployeeName())
                .like(StringUtils.isNotEmpty(query.getUsername()), "user.username", query.getUsername())
                .eq(query.getStateCode() != null, "user.state_code", query.getStateCode());

        IPage<UserListVO> voPage = baseMapper.selectUserPage(new Page<>(query.getCurrent(), query.getSize()), queryWrapper);

        trans(voPage.getRecords(), UserListVO.class);

        return voPage;
    }

    private <T> void trans(List<T> entityList, Class<T> entityType) {

        TransUtils.trans(entityList, entityType, new DBTransRule[]{
                new DBTransRule<>(
                        new String[]{"employeeId", "employeeName", "employeeGenderCode"},
                        EmployeeMapper.class,
                        new String[]{"id", "name", "gender_code"}
                ),
                new DBTransRule<>(
                        new String[]{"roleId", "roleName"},
                        RoleMapper.class,
                        new String[]{"id", "name"}
                ),
        });

        TransUtils.trans(entityList, entityType, new DictTransRule[]{
                new DictTransRule(DictTypeCodeEnum.USER_STATE, "stateCode"),
                new DictTransRule(DictTypeCodeEnum.GENDER, "employeeGenderCode")
        });
    }

    @Override
    public UserDetailVO getUserById(Long id) {

        UserDetailVO detailVO = AbstractUserConverter.INSTANCE.do2DetailVO(getById(id));

        trans(Collections.singletonList(detailVO), UserDetailVO.class);

        return detailVO;
    }

    @Override
    public boolean saveUser(UserSaveDTO saveDTO) {

        UserDO dataObj = AbstractUserConverter.INSTANCE.saveDTO2DO(saveDTO);

        dataObj.setSalt(CommonUtils.uuid());
        dataObj.setPassword(SecurityUtils.md5WithSalt("123456", dataObj.getSalt(), qdProperties.getPasswordSaltTimes()));

        return save(dataObj);
    }

    @Override
    public boolean updateUserById(Long id, UserSaveDTO saveDTO) {

        UserDO dataObj = AbstractUserConverter.INSTANCE.saveDTO2DO(saveDTO);

        dataObj.setId(id);
        dataObj.setUpdateUserId(UserUtils.getId());
        dataObj.setUpdateTime(LocalDateTime.now());

        return updateById(dataObj);
    }

    @Override
    public boolean removeUserById(Long id) {

        UserDO dataObj = new UserDO();

        dataObj.setId(id);
        dataObj.setUpdateUserId(UserUtils.getId());
        dataObj.setUpdateTime(LocalDateTime.now());

        return removeByIdWithFill(dataObj);
    }

}
